From 82e5171fba7d6561bae20630457622386dc3bc46 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Sat, 19 Nov 2016 12:07:40 +0100 Subject: [PATCH] fast-float: make float to cairo conversion take clipping into account --- extensions/fast-float.c | 100 +++++++++++++++++++++++++++++++++------- 1 file changed, 83 insertions(+), 17 deletions(-) diff --git a/extensions/fast-float.c b/extensions/fast-float.c index 737fa83..392bcb5 100644 --- a/extensions/fast-float.c +++ b/extensions/fast-float.c @@ -114,7 +114,7 @@ babl_lookup (BablLookup *lookup, lookup->bitmask[i/32] |= (1UL<<(i & 31)); } - return lookup->table[i-1] * (1.0-dx) + + return lookup->table[i-1] * (1.0f-dx) + lookup->table[i] * (dx); } else @@ -338,36 +338,83 @@ conv_rgbaF_linear_rgbA8_gamma (unsigned char *src, while (n--) { float alpha = fsrc[3]; - if (alpha == 1.0) + if (alpha >= 1.0) { - *cdst++ = linear_to_gamma_2_2_lut (*fsrc++) * 0xff + 0.5f; - *cdst++ = linear_to_gamma_2_2_lut (*fsrc++) * 0xff + 0.5f; - *cdst++ = linear_to_gamma_2_2_lut (*fsrc++) * 0xff + 0.5f; + int val = linear_to_gamma_2_2_lut (fsrc[0]) * 0xff + 0.5f; + *cdst++ = val > 0xff ? 0xff : val < 0 ? 0 : val; + val = linear_to_gamma_2_2_lut (fsrc[1]) * 0xff + 0.5f; + *cdst++ = val > 0xff ? 0xff : val < 0 ? 0 : val; + val = linear_to_gamma_2_2_lut (fsrc[2]) * 0xff + 0.5f; + *cdst++ = val > 0xff ? 0xff : val < 0 ? 0 : val; *cdst++ = 0xff; - fsrc++; + fsrc+=4; } - else if (alpha == 0.0) + else if (alpha <= 0.0) { - *cdst++ = 0.0; - *cdst++ = 0.0; - *cdst++ = 0.0; - *cdst++ = 0.0; + *((uint32_t*)(cdst))=0; + cdst+=4; fsrc+=4; } else { float balpha = alpha * 0xff; - *cdst++ = linear_to_gamma_2_2_lut (*fsrc++) * balpha + 0.5f; - *cdst++ = linear_to_gamma_2_2_lut (*fsrc++) * balpha + 0.5f; - *cdst++ = linear_to_gamma_2_2_lut (*fsrc++) * balpha + 0.5f; - *cdst++ = balpha + 0.5; - fsrc++; + int val = linear_to_gamma_2_2_lut (fsrc[0]) * balpha + 0.5f; + *cdst++ = val > 0xff ? 0xff : val < 0 ? 0 : val; + val = linear_to_gamma_2_2_lut (fsrc[1]) * balpha + 0.5f; + *cdst++ = val > 0xff ? 0xff : val < 0 ? 0 : val; + val = linear_to_gamma_2_2_lut (fsrc[2]) * balpha + 0.5f; + *cdst++ = val > 0xff ? 0xff : val < 0 ? 0 : val; + *cdst++ = balpha + 0.5f; + fsrc+=4; } } return samples; } +static long +conv_rgbaF_linear_rgbA8_gamma_cairo (unsigned char *src, + unsigned char *dst, + long samples) +{ + float *fsrc = (float *) src; + unsigned char *cdst = (unsigned char *) dst; + int n = samples; + while (n--) + { + float alpha = fsrc[3]; + if (alpha >= 1.0) + { + int val = linear_to_gamma_2_2_lut (fsrc[2]) * 0xff + 0.5f; + *cdst++ = val > 0xff ? 0xff : val < 0 ? 0 : val; + val = linear_to_gamma_2_2_lut (fsrc[1]) * 0xff + 0.5f; + *cdst++ = val > 0xff ? 0xff : val < 0 ? 0 : val; + val = linear_to_gamma_2_2_lut (fsrc[0]) * 0xff + 0.5f; + *cdst++ = val > 0xff ? 0xff : val < 0 ? 0 : val; + *cdst++ = 0xff; + fsrc+=4; + } + else if (alpha <= 0.0) + { + *((uint32_t*)(cdst))=0; + cdst+=4; + fsrc+=4; + } + else + { + float balpha = alpha * 0xff; + int val = linear_to_gamma_2_2_lut (fsrc[2]) * balpha + 0.5f; + *cdst++ = val > 0xff ? 0xff : val < 0 ? 0 : val; + val = linear_to_gamma_2_2_lut (fsrc[1]) * balpha + 0.5f; + *cdst++ = val > 0xff ? 0xff : val < 0 ? 0 : val; + val = linear_to_gamma_2_2_lut (fsrc[0]) * balpha + 0.5f; + *cdst++ = val > 0xff ? 0xff : val < 0 ? 0 : val; + *cdst++ = balpha + 0.5f; + fsrc+=4; + } + } + return samples; +} static INLINE long conv_rgbAF_linear_rgbAF_gamma (unsigned char *src, @@ -552,6 +599,7 @@ init (void) float f; float a; + /* tweaking the precision - does impact speed.. */ fast_pow = babl_lookup_new (core_lookup, NULL, 0.0, 1.0, 0.00033); fast_rpow = babl_lookup_new (core_rlookup, NULL, 0.0, 1.0, 0.00033); @@ -565,9 +613,27 @@ init (void) } + + { + const Babl *f32 = babl_format_new ( + "name", "cairo-ARGB32", + babl_model ("R'aG'aB'aA"), + babl_type ("u8"), + babl_component ("B'a"), + babl_component ("G'a"), + babl_component ("R'a"), + babl_component ("A"), + NULL + ); + + + babl_conversion_new (rgbaF_linear, f32, "linear", conv_rgbaF_linear_rgbA8_gamma_cairo, NULL); + } + + o (rgbaF_linear, rgbA8_gamma); + o (rgbAF_linear, rgbAF_gamma); o (rgbaF_linear, rgbAF_gamma); - o (rgbaF_linear, rgbA8_gamma); o (rgbaF_linear, rgbaF_gamma); o (rgbaF_gamma, rgbaF_linear); o (rgbF_linear, rgbF_gamma); -- 2.30.2